# 数据结构
# 列表：列表是可变的，这是它区别于字符串和元组的最重要的特点，一句话概括即：列表可以修改，而字符串和元组不能。
aList = [1, 2, 15, 1, 5, 3, 99, 10, 15, 1]
print(aList)
print(aList.count(1))  # 返回 x 在列表中出现的次数。
aList.append(100)  # 把一个元素添加到列表的结尾，相当于 a[len(a):] = [x]。
aList.extend(aList)  # 通过添加指定列表的所有元素来扩充列表，相当于 a[len(a):] = L。
# 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引，例如 a.insert(0, x) 会插入到整个列表之前，而 a.insert(len(a), x) 相当于 a.append(x) 。
aList.insert(2, 1000)
aList.remove(1000)
print(aList)

# 列表推导式
vec = [3, 4, 5, 6]
print([3*x for x in vec])
print([[x, x**2] for x in vec])
# 可以用 if 子句作为过滤器：
print([3*x for x in vec if x > 3])

vec1 = [2, 4, 6]
vec2 = [4, 3, -9]
print([x*y for x in vec1 for y in vec2])
print([vec1[i]*vec2[i] for i in range(len(vec1))])
print([str(round(355/113, i)) for i in range(1, 6)])

# 嵌套列表
# 3X4矩阵
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
# 转化为4X3矩阵
print([[row[i] for row in matrix] for i in range(4)])
# 另一种
transposed = []
for i in range(4):
    transposed.append([row[i] for row in matrix])
print(transposed)
# 另一种
transposed = []
for i in range(4):
    # the following 3 lines implement the nested listcomp
    transposed_row = []
    for row in matrix:
        transposed_row.append(row[i])
    transposed.append(transposed_row)
print(transposed)

# del 语句
# 使用 del 语句可以从一个列表中依索引而不是值来删除一个元素。这与使用 pop() 返回一个值不同。可以用 del 语句从列表中删除一个切割，或清空整个列表
a = [1, 12, 23, 4523, 3, 45, 213, 56, 87, 231]
del a[0]
print(a)
del a[2:4]
print(a)
del a[:]
print(a)
# 也可以用 del 删除实体变量：
del a

# 集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。
basket = {'a', 'bdf', 'jljkl', 'a', 'b', 'ac', 'b'}
print(basket)
# 以下演示了两个集合的操作
a = set('abracadabra')
b = set('alacazam')
print(a)  # a 中唯一的字母
print(a-b)  # 在 a 中的字母，但不在 b 中
print(a | b)  # 在 a 或 b 中的字母
print(a & b)  # 在 a 和 b 中都有的字母
print(a ^ b)  # 在 a 或 b 中的字母，但不同时在 a 和 b 中
# 集合也支持推导式：
a = {x for x in 'abracadabra' if x not in 'abc'}
print(a)

# 字典
tel = {'jack': 4098, 'sape': 4139}
print(tel['jack'])
print(tel)
del tel
tel = {'guido': 4127, 'irv': 4127, 'jack': 4098}
tel['abc'] = 1982
print(tel)
print(list(tel.keys()))
print(list(tel.values()))
print(sorted(tel.values()))
print('abc' in tel)

# 构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式，列表推导式指定特定的键值对：
adict = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
print(adict)
# 字典推导可以用来创建任意键和值的表达式词典：
print({x: x**2 for x in (2, 4, 6)})
# 如果关键字只是简单的字符串，使用关键字参数指定键值对有时候更方便：
print(dict(sape=4139, guido=4127, jack=4098))

# 字典中遍历时，关键字和对应的值可以使用 items() 方法同时解读出来：
knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
    print(k, v)

# 序列中遍历时，索引位置和对应值可以使用 enumerate() 函数同时得到：
for i, v in enumerate(['tic', 'tac', 'toe']):
    print(i, v)

# 同时遍历两个或更多的序列，可以使用 zip() 组合：
questions = ['name', 'quest', 'favorite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
    print('What is your {0}? It is {1}.'.format(q, a))

# 要反向遍历一个序列，首先指定这个序列，然后调用 reversed() 函数：
for i in reversed(range(1, 10, 2)):
    print(i)

# 要按顺序遍历一个序列，使用 sorted() 函数返回一个已排序的序列，并不修改原值：
